home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 October / EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso / Aminet / dev / cross / dasm202.lha / dasm-2.02 / ops.c < prev    next >
C/C++ Source or Header  |  1995-03-02  |  19KB  |  953 lines

  1.  
  2. /*
  3.  *  OPS.C
  4.  *
  5.  *  Handle mnemonics and pseudo ops
  6.  *
  7.  */
  8.  
  9. #include "asm.h"
  10.  
  11. ubyte     Gen[256];
  12. ubyte     OrgFill = DEFORGFILL;
  13. int     Glen;
  14.  
  15. extern MNE    Mne6502[];
  16. extern MNE    Mne6803[];
  17. extern MNE    MneHD6303[];
  18. extern MNE    Mne68705[];
  19. extern MNE    Mne68HC11[];
  20.  
  21. void generate(void);
  22. void genfill(int fill, long bytes);
  23. void pushif(int bool);
  24. int gethexdig(int c);
  25.  
  26. /*
  27.  *  An opcode modifies the SEGMENT flags in the following ways:
  28.  */
  29.  
  30. void
  31. v_processor(char *str, MNE *dummy)
  32. {
  33.     static int      called;
  34.  
  35.     if (called)
  36.     return;
  37.     called = 1;
  38.     if (strcmp(str,"6502") == 0) {
  39.     addhashtable(Mne6502);
  40.     MsbOrder = 0;        /*    lsb,msb */
  41.     Processor = 6502;
  42.     }
  43.     if (strcmp(str,"6803") == 0) {
  44.     addhashtable(Mne6803);
  45.     MsbOrder = 1;        /*    msb,lsb */
  46.     Processor = 6803;
  47.     }
  48.     if (strcmp(str,"HD6303") == 0 || strcmp(str, "hd6303") == 0) {
  49.     addhashtable(Mne6803);
  50.     addhashtable(MneHD6303);
  51.     MsbOrder = 1;        /*    msb,lsb */
  52.     Processor = 6303;
  53.     }
  54.     if (strcmp(str,"68705") == 0) {
  55.     addhashtable(Mne68705);
  56.     MsbOrder = 1;        /*    msb,lsb */
  57.     Processor = 68705;
  58.     }
  59.     if (strcmp(str,"68HC11") == 0 || strcmp(str, "68hc11") == 0) {
  60.     addhashtable(Mne68HC11);
  61.     MsbOrder = 1;        /*    msb,lsb */
  62.     Processor = 6811;
  63.     }
  64.     if (!Processor)
  65.     asmerr(20,1);
  66. }
  67.  
  68. #define badcode(mne,adrmode)    (!(mne->okmask & (1 << adrmode)))
  69.  
  70. void
  71. v_mnemonic(char *str, MNE *mne)
  72. {
  73.     register int addrmode;
  74.     register SYMBOL *sym;
  75.     SYMBOL *symbase;
  76.     int     opsize;
  77.  
  78.     Csegment->flags |= SF_REF;
  79.     programlabel();
  80.     symbase = eval(str, 1);
  81.  
  82.     if (Xtrace)
  83.     printf("PC: %04lx  MNE: %s  addrmode: %d  ",
  84.            Csegment->org, mne->name, symbase->addrmode);
  85.     for (sym = symbase; sym; sym = sym->next) {
  86.     if (sym->flags & SYM_UNKNOWN) {
  87.         ++Redo;
  88.         Redo_why |= 1 << 0;
  89.     }
  90.     }
  91.     sym = symbase;
  92.     if (sym->addrmode == AM_IMM8 || sym->addrmode == AM_BYTEADR) {
  93.     if (sym->next) {
  94.         sym->addrmode = AM_BITMOD;
  95.         if (sym->next->next)
  96.         sym->addrmode = AM_BITBRAMOD;
  97.     }
  98.     }
  99.     addrmode = sym->addrmode;
  100.     if ((sym->flags & SYM_UNKNOWN) || sym->value >= 0x100)
  101.     opsize = 2;
  102.     else
  103.     opsize = (sym->value) ? 1 : 0;
  104.     while (badcode(mne,addrmode) && Cvt[addrmode])
  105.     addrmode = Cvt[addrmode];
  106.     if (Xtrace)
  107.     printf("mnemask: %08lx adrmode: %d  Cvt[am]: %d\n",
  108.         mne->okmask, addrmode, Cvt[addrmode]);
  109.     if (badcode(mne,addrmode)) {
  110.     asmerr(5,0);
  111.     freesymbollist(symbase);
  112.     return;
  113.     }
  114.     if (Mnext >= 0 && Mnext < NUMOC) {            /*    Force    */
  115.     addrmode = Mnext;
  116.     if (badcode(mne,addrmode)) {
  117.         asmerr(19,0);
  118.         freesymbollist(symbase);
  119.         return;
  120.     }
  121.     }
  122.     if (Xtrace)
  123.     printf("final addrmode = %d\n", addrmode);
  124.  
  125.     while (opsize > Opsize[addrmode]) {
  126.     if (Cvt[addrmode] == 0 || badcode(mne,Cvt[addrmode])) {
  127.         if (sym->flags & SYM_UNKNOWN)
  128.         break;
  129.         puts("asmerr 14:");
  130.         asmerr(14,0);
  131.         break;
  132.     }
  133.     addrmode = Cvt[addrmode];
  134.     }
  135.     Glen = Adrbytes[addrmode];
  136.     Gen[0] = mne->opcode[addrmode];
  137.     Gen[1] = sym->value;
  138.     if (Opsize[addrmode] > 1) {
  139.     if (MsbOrder) {
  140.         Gen[1] = sym->value >> 8;
  141.         Gen[2] = sym->value;
  142.     } else {
  143.         Gen[2] = sym->value >> 8;
  144.     }
  145.     }
  146.     switch(addrmode) {
  147.     case AM_BITMOD:
  148.     sym = symbase->next;
  149.     if (!(sym->flags & SYM_UNKNOWN) && sym->value >= 0x100)
  150.         asmerr(14,0);
  151.     Gen[1] = sym->value;
  152.     if (!(symbase->flags & SYM_UNKNOWN)) {
  153.         if (symbase->value > 7)
  154.         asmerr(15,0);
  155.         else
  156.         Gen[0] += symbase->value << 1;
  157.     }
  158.     break;
  159.     case AM_BITBRAMOD:
  160.     if (!(symbase->flags & SYM_UNKNOWN)) {
  161.         if (symbase->value > 7)
  162.         asmerr(15,0);
  163.         else
  164.         Gen[0] += symbase->value << 1;
  165.     }
  166.     sym = symbase->next;
  167.     if (!(sym->flags & SYM_UNKNOWN) && sym->value >= 0x100)
  168.         asmerr(14,0);
  169.     Gen[1] = sym->value;
  170.     sym = sym->next;
  171.     case AM_REL:
  172.     if (!(sym->flags & SYM_UNKNOWN)) {
  173.         long    pc;
  174.         ubyte   pcf;
  175.         long    dest;
  176.         pc = (Csegment->flags & SF_RORG) ? Csegment->rorg : Csegment->org;
  177.         pcf= (Csegment->flags & SF_RORG) ? Csegment->rflags : Csegment->flags;
  178.         if ((pcf & 3) == 0) {
  179.         dest = sym->value - pc - Adrbytes[addrmode];
  180.         if (dest >= 128 || dest < -128)
  181.         asmerr(10,0);
  182.         }
  183.         Gen[(addrmode == AM_REL) ? 1 : 2] = dest & 0xFF;
  184.     }
  185.     break;
  186.     }
  187.     generate();
  188.     freesymbollist(symbase);
  189. }
  190.  
  191. void
  192. v_trace(char *str, MNE *dummy)
  193. {
  194.     if (str[1] == 'n')
  195.     Xtrace = 1;
  196.     else
  197.     Xtrace = 0;
  198. }
  199.  
  200. void
  201. v_list(char *str, MNE *dummy)
  202. {
  203.     programlabel();
  204.     if (str[1] == 'n')
  205.     Incfile->flags &= ~INF_NOLIST;
  206.     else
  207.     Incfile->flags |=  INF_NOLIST;
  208. }
  209.  
  210. void
  211. v_include(char *str, MNE *dummy)
  212. {
  213.     char    *buf;
  214.  
  215.     programlabel();
  216.     if (*str == '\"') {
  217.     buf = malloc(strlen(str)+1-1);
  218.     strcpy(buf, str+1);
  219.     for (str = buf; *str && *str != '\"'; ++str);
  220.     *str = 0;
  221.     pushinclude(buf);
  222.     free(buf);
  223.     } else {
  224.     pushinclude(str);
  225.     }
  226. }
  227.  
  228. void
  229. v_seg(char *str, MNE *dummy)
  230. {
  231.     register SEGMENT *seg;
  232.  
  233.     for (seg = Seglist; seg; seg = seg->next) {
  234.     if (strcmp(str, seg->name) == 0) {
  235.         Csegment = seg;
  236.         programlabel();
  237.         return;
  238.     }
  239.     }
  240.     Csegment = seg = (SEGMENT *)zmalloc(sizeof(SEGMENT));
  241.     seg->next = Seglist;
  242.     seg->name = strcpy(malloc(strlen(str)+1), str);
  243.     seg->flags= seg->rflags = seg->initflags = seg->initrflags = SF_UNKNOWN;
  244.     Seglist = seg;
  245.     if (Mnext == AM_BSS)
  246.     seg->flags |= SF_BSS;
  247.     programlabel();
  248. }
  249.  
  250. void
  251. v_hex(char *str, MNE *dummy)
  252. {
  253.     register int i;
  254.     register int result;
  255.  
  256.     programlabel();
  257.     Glen = 0;
  258.     for (i = 0; str[i]; ++i) {
  259.     if (str[i] == ' ')
  260.         continue;
  261.     result = (gethexdig(str[i]) << 4) + gethexdig(str[i+1]);
  262.     if (str[++i] == 0)
  263.         break;
  264.     Gen[Glen++] = result;
  265.     }
  266.     generate();
  267. }
  268.  
  269. int
  270. gethexdig(int c)
  271. {
  272.     if (c >= '0' && c <= '9')
  273.     return(c - '0');
  274.     if (c >= 'a' && c <= 'f')
  275.     return(c - 'a' + 10);
  276.     if (c >= 'A' && c <= 'F')
  277.     return(c - 'A' + 10);
  278.     asmerr(0,0);
  279.     puts("(Must be a valid hex digit)");
  280.     if (F_listfile)
  281.     fputs("(Must be a valid hex digit)\n", FI_listfile);
  282.     return(0);
  283. }
  284.  
  285. void
  286. v_err(char *str, MNE *dummy)
  287. {
  288.     programlabel();
  289.     asmerr(11, 1);
  290.     exit(1);
  291. }
  292.  
  293. void
  294. v_dc(char *str, MNE *mne)
  295. {
  296.     register SYMBOL *sym;
  297.     register SYMBOL *tmp;
  298.     register ulong  value;
  299.     char *macstr;
  300.     char vmode = 0;
  301.  
  302.     Glen = 0;
  303.     programlabel();
  304. #if OlafByte
  305.     /* for byte, .byte, word, .word, long, .long */
  306.     if (mne->name[0] != 'd') {
  307.     static char tmp[4];
  308.     strcpy(tmp, "x.x");
  309.     tmp[2] = mne->name[0];
  310.     findext(tmp);
  311.     }
  312. #endif
  313.     if (mne->name[1] == 'v') {
  314.     register int i;
  315.     vmode = 1;
  316.     for (i = 0; str[i] && str[i] != ' '; ++i);
  317.     tmp = findsymbol(str, i);
  318.     str += i;
  319.     if (tmp == NULL) {
  320.         puts("EQM label not found");
  321.         return;
  322.     }
  323.     if (tmp->flags & SYM_MACRO) {
  324.         macstr = (void *)tmp->string;
  325.     } else {
  326.         puts("must specify EQM label for DV");
  327.         return;
  328.     }
  329.     }
  330.     sym = eval(str, 0);
  331.     for (; sym; sym = sym->next) {
  332.     value = sym->value;
  333.     if (sym->flags & SYM_UNKNOWN) {
  334.         ++Redo;
  335.         Redo_why |= (1 << 2);
  336.     }
  337.     if (sym->flags & SYM_STRING) {
  338.         register ubyte *ptr = (void *)sym->string;
  339.         while ((value = *ptr) != 0) {
  340.         if (vmode) {
  341.             setspecial(value, 0);
  342.             tmp = eval(macstr, 0);
  343.             value = tmp->value;
  344.             if (tmp->flags & SYM_UNKNOWN) {
  345.             ++Redo;
  346.             Redo_why |= (1 << 3);
  347.             }
  348.             freesymbollist(tmp);
  349.         }
  350.         switch(Mnext) {
  351.         default:
  352.         case AM_BYTE:
  353.             Gen[Glen++] = value & 0xFF;
  354.             break;
  355.         case AM_WORD:
  356.             if (MsbOrder) {
  357.             Gen[Glen++] = (value >> 8) & 0xFF;
  358.             Gen[Glen++] = value & 0xFF;
  359.             } else {
  360.             Gen[Glen++] = value & 0xFF;
  361.             Gen[Glen++] = (value >> 8) & 0xFF;
  362.             }
  363.             break;
  364.         case AM_LONG:
  365.             if (MsbOrder) {
  366.             Gen[Glen++] = (value >> 24)& 0xFF;
  367.             Gen[Glen++] = (value >> 16)& 0xFF;
  368.             Gen[Glen++] = (value >> 8) & 0xFF;
  369.             Gen[Glen++] = value & 0xFF;
  370.             } else {
  371.             Gen[Glen++] = value & 0xFF;
  372.             Gen[Glen++] = (value >> 8) & 0xFF;
  373.             Gen[Glen++] = (value >> 16)& 0xFF;
  374.             Gen[Glen++] = (value >> 24)& 0xFF;
  375.             }
  376.             break;
  377.         }
  378.         ++ptr;
  379.         }
  380.     } else {
  381.         if (vmode) {
  382.         setspecial(value, sym->flags);
  383.         tmp = eval(macstr, 0);
  384.         value = tmp->value;
  385.         if (tmp->flags & SYM_UNKNOWN) {
  386.             ++Redo;
  387.             Redo_why |= 1 << 4;
  388.         }
  389.         freesymbollist(tmp);
  390.         }
  391.         switch(Mnext) {
  392.         default:
  393.         case AM_BYTE:
  394.         Gen[Glen++] = value & 0xFF;
  395.         break;
  396.         case AM_WORD:
  397.         if (MsbOrder) {
  398.             Gen[Glen++] = (value >> 8) & 0xFF;
  399.             Gen[Glen++] = value & 0xFF;
  400.         } else {
  401.             Gen[Glen++] = value & 0xFF;
  402.             Gen[Glen++] = (value >> 8) & 0xFF;
  403.         }
  404.         break;
  405.         case AM_LONG:
  406.         if (MsbOrder) {
  407.             Gen[Glen++] = (value >> 24)& 0xFF;
  408.             Gen[Glen++] = (value >> 16)& 0xFF;
  409.             Gen[Glen++] = (value >> 8) & 0xFF;
  410.             Gen[Glen++] = value & 0xFF;
  411.         } else {
  412.             Gen[Glen++] = value & 0xFF;
  413.             Gen[Glen++] = (value >> 8) & 0xFF;
  414.             Gen[Glen++] = (value >> 16)& 0xFF;
  415.             Gen[Glen++] = (value >> 24)& 0xFF;
  416.         }
  417.         break;
  418.         }
  419.     }
  420.     }
  421.     generate();
  422.     freesymbollist(sym);
  423. }
  424.  
  425. void
  426. v_ds(char *str, MNE *dummy)
  427. {
  428.     register SYMBOL *sym;
  429.     int mult = 1;
  430.     long filler = 0;
  431.  
  432.     if (Mnext == AM_WORD)
  433.     mult = 2;
  434.     if (Mnext == AM_LONG)
  435.     mult = 4;
  436.     programlabel();
  437.     if ((sym = eval(str, 0)) != NULL) {
  438.     if (sym->next)
  439.         filler = sym->next->value;
  440.     if (sym->flags & SYM_UNKNOWN) {
  441.         ++Redo;
  442.         Redo_why |= 1 << 5;
  443.     } else {
  444.         if (sym->next && sym->next->flags & SYM_UNKNOWN) {
  445.         ++Redo;
  446.         Redo_why |= 1 << 5;
  447.         }
  448.         genfill(filler, sym->value * mult);
  449.     }
  450.     freesymbollist(sym);
  451.     }
  452. }
  453.  
  454. void
  455. v_org(char *str, MNE *dummy)
  456. {
  457.     register SYMBOL *sym = eval(str, 0);
  458.  
  459.     Csegment->org = sym->value;
  460.     if (sym->flags & SYM_UNKNOWN)
  461.     Csegment->flags |= SYM_UNKNOWN;
  462.     else
  463.     Csegment->flags &= ~SYM_UNKNOWN;
  464.     if (Csegment->initflags & SYM_UNKNOWN) {
  465.     Csegment->initorg = sym->value;
  466.     Csegment->initflags = sym->flags;
  467.     }
  468.     if (sym->next) {
  469.     OrgFill = sym->next->value;
  470.     if (sym->next->flags & SYM_UNKNOWN)
  471.         asmerr(18,1);
  472.     }
  473.     programlabel();
  474.     freesymbollist(sym);
  475. }
  476.  
  477. void
  478. v_rorg(char *str, MNE *dummy)
  479. {
  480.     register SYMBOL *sym = eval(str, 0);
  481.  
  482.     Csegment->flags |= SF_RORG;
  483.     if (sym->addrmode != AM_IMP) {
  484.     Csegment->rorg = sym->value;
  485.     if (sym->flags & SYM_UNKNOWN)
  486.         Csegment->rflags |= SYM_UNKNOWN;
  487.     else
  488.         Csegment->rflags &= ~SYM_UNKNOWN;
  489.     if (Csegment->initrflags & SYM_UNKNOWN) {
  490.         Csegment->initrorg = sym->value;
  491.         Csegment->initrflags = sym->flags;
  492.     }
  493.     }
  494.     programlabel();
  495.     freesymbollist(sym);
  496. }
  497.  
  498. void
  499. v_rend(char *str, MNE *dummy)
  500. {
  501.     programlabel();
  502.     Csegment->flags &= ~SF_RORG;
  503. }
  504.  
  505. void
  506. v_align(char *str, MNE *dummy)
  507. {
  508.     SYMBOL *sym = eval(str, 0);
  509.     ubyte   fill = 0;
  510.     ubyte   rorg = Csegment->flags & SF_RORG;
  511.  
  512.     if (rorg)
  513.     Csegment->rflags |= SF_REF;
  514.     else
  515.     Csegment->flags |= SF_REF;
  516.     if (sym->next) {
  517.     if (sym->next->flags & SYM_UNKNOWN) {
  518.         ++Redo;
  519.         Redo_why |= 1 << 6;
  520.     } else {
  521.         fill = sym->value;
  522.     }
  523.     }
  524.     if (rorg) {
  525.     if ((Csegment->rflags | sym->flags) & SYM_UNKNOWN) {
  526.         ++Redo;
  527.         Redo_why |= 1 << 7;
  528.     } else {
  529.         register long n = sym->value - (Csegment->rorg % sym->value);
  530.         if (n != sym->value)
  531.         genfill(fill, n);
  532.     }
  533.     } else {
  534.     if ((Csegment->flags | sym->flags) & SYM_UNKNOWN) {
  535.         ++Redo;
  536.         Redo_why |= 1 << 8;
  537.     } else {
  538.         register long n = sym->value - (Csegment->org % sym->value);
  539.         if (n != sym->value)
  540.         genfill(fill, n);
  541.     }
  542.     }
  543.     freesymbollist(sym);
  544.     programlabel();
  545. }
  546.  
  547. void
  548. v_subroutine(char *str, MNE *dummy)
  549. {
  550.     ++Lastlocalindex;
  551.     Localindex = Lastlocalindex;
  552.     programlabel();
  553. }
  554.  
  555. void
  556. v_equ(char *str, MNE *dummy)
  557. {
  558.     SYMBOL *sym = eval(str, 0);
  559.     SYMBOL *lab;
  560.  
  561.     lab = findsymbol(Av[0], strlen(Av[0]));
  562.     if (!lab)
  563.     lab = createsymbol(Av[0], strlen(Av[0]));
  564.     if (!(lab->flags & SYM_UNKNOWN)) {
  565.     if (sym->flags & SYM_UNKNOWN) {
  566.         ++Redo;
  567.         Redo_why |= 1 << 9;
  568.     } else {
  569.         if (lab->value != sym->value) {
  570.         asmerr(13,0);
  571.         printf("old value: $%04lx  new value: $%04lx\n",
  572.                lab->value, sym->value);
  573.         ++Redo;
  574.         Redo_why |= 1 << 10;
  575.         }
  576.     }
  577.     }
  578.     lab->value = sym->value;
  579.     lab->flags = sym->flags & (SYM_UNKNOWN|SYM_STRING);
  580.     lab->string = sym->string;
  581.     sym->flags &= ~(SYM_STRING|SYM_MACRO);
  582.     freesymbollist(sym);
  583. }
  584.  
  585. void
  586. v_eqm(char *str, MNE *dummy)
  587. {
  588.     register SYMBOL *lab;
  589.     register int len = strlen(Av[0]);
  590.  
  591.     if ((lab = findsymbol(Av[0], len)) != NULL) {
  592.     if (lab->flags & SYM_STRING)
  593.         free(lab->string);
  594.     } else {
  595.     lab = createsymbol(Av[0], len);
  596.     }
  597.     lab->value = 0;
  598.     lab->flags = SYM_STRING | SYM_SET | SYM_MACRO;
  599.     lab->string = strcpy(malloc(strlen(str)+1), str);
  600. }
  601.  
  602. void
  603. v_echo(char *str, MNE *dummy)
  604. {
  605.     SYMBOL *sym = eval(str, 0);
  606.     SYMBOL *s;
  607.     char buf[256];
  608.  
  609.     for (s = sym; s; s = s->next) {
  610.     if (!(s->flags & SYM_UNKNOWN)) {
  611.         if (s->flags & (SYM_MACRO|SYM_STRING))
  612.         sprintf(buf,"%s", s->string);
  613.         else
  614.         sprintf(buf,"$%lx", s->value);
  615.         if (FI_listfile)
  616.         fprintf(FI_listfile, " %s", buf);
  617.         printf(" %s", buf);
  618.     }
  619.     }
  620.     puts("");
  621.     if (FI_listfile)
  622.     putc('\n', FI_listfile);
  623. }
  624.  
  625. void
  626. v_set(char *str, MNE *dummy)
  627. {
  628.     SYMBOL *sym = eval(str, 0);
  629.     SYMBOL *lab;
  630.  
  631.     lab = findsymbol(Av[0], strlen(Av[0]));
  632.     if (!lab)
  633.     lab = createsymbol(Av[0], strlen(Av[0]));
  634.     lab->value = sym->value;
  635.     lab->flags = sym->flags & (SYM_UNKNOWN|SYM_STRING);
  636.     lab->string = sym->string;
  637.     sym->flags &= ~(SYM_STRING|SYM_MACRO);
  638.     freesymbollist(sym);
  639. }
  640.  
  641. void
  642. v_execmac(char *str, MACRO *mac)
  643. {
  644.     register INCFILE *inc;
  645.     STRLIST *base;
  646.     register STRLIST **psl, *sl;
  647.     register char *s1;
  648.  
  649.     programlabel();
  650.  
  651.     if (Mlevel == MAXMACLEVEL) {
  652.     puts("infinite macro recursion");
  653.     return;
  654.     }
  655.     ++Mlevel;
  656.     base = (STRLIST *)malloc(sizeof(STRLIST)-4+strlen(str)+1);
  657.     base->next = NULL;
  658.     strcpy(base->buf, str);
  659.     psl = &base->next;
  660.     while (*str && *str != '\n') {
  661.     s1 = str;
  662.     while (*str && *str != '\n' && *str != ',')
  663.         ++str;
  664.     sl = (STRLIST *)malloc(sizeof(STRLIST)-4+1+(str-s1));
  665.     sl->next = NULL;
  666.     *psl = sl;
  667.     psl = &sl->next;
  668.     memcpy(sl->buf, s1, (str-s1));
  669.     sl->buf[str-s1] = 0;
  670.     if (*str == ',')
  671.         ++str;
  672.     while (*str == ' ')
  673.         ++str;
  674.     }
  675.  
  676.     inc = (INCFILE *)zmalloc(sizeof(INCFILE));
  677.     inc->next = Incfile;
  678.     inc->name = mac->name;
  679.     inc->fi   = Incfile->fi;    /* garbage */
  680.     inc->lineno = 0;
  681.     inc->flags = INF_MACRO;
  682.     inc->saveidx = Localindex;
  683. #if OlafDol
  684.     inc->savedolidx = Localdollarindex;
  685. #endif
  686.     inc->strlist = mac->strlist;
  687.     inc->args      = base;
  688.     Incfile = inc;
  689.  
  690.     ++Lastlocalindex;
  691.     Localindex = Lastlocalindex;
  692. #if OlafDol
  693.     ++Lastlocaldollarindex;
  694.     Localdollarindex = Lastlocaldollarindex;
  695. #endif
  696. }
  697.  
  698. void
  699. v_end(char *str, MNE *dummy)
  700. {
  701.     puts("END not implemented yet");
  702. }
  703.  
  704. void
  705. v_endm(char *str, MNE *dummy)
  706. {
  707.     register INCFILE *inc = Incfile;
  708.     register STRLIST *args, *an;
  709.  
  710.     programlabel();
  711.     if (inc->flags & INF_MACRO) {
  712.     --Mlevel;
  713.     for (args = inc->args; args; args = an) {
  714.         an = args->next;
  715.         free(args);
  716.     }
  717.     Localindex = inc->saveidx;
  718. #if OlafDol
  719.     Localdollarindex = inc->savedolidx;
  720. #endif
  721.     Incfile = inc->next;
  722.     free(inc);
  723.     return;
  724.     }
  725.     puts("not within a macro");
  726. }
  727.  
  728. void
  729. v_mexit(char *str, MNE *dummy)
  730. {
  731.     v_endm(NULL, NULL);
  732. }
  733.  
  734. void
  735. v_ifconst(char *str, MNE *dummy)
  736. {
  737.     SYMBOL *sym;
  738.  
  739.     programlabel();
  740.     sym = eval(str, 0);
  741.     pushif(sym->flags == 0);
  742.     freesymbollist(sym);
  743. }
  744.  
  745. void
  746. v_ifnconst(char *str, MNE *dummy)
  747. {
  748.     SYMBOL *sym;
  749.  
  750.     programlabel();
  751.     sym = eval(str, 0);
  752.     pushif(sym->flags != 0);
  753.     freesymbollist(sym);
  754. }
  755.  
  756. void
  757. v_if(char *str, MNE *dummy)
  758. {
  759.     SYMBOL *sym;
  760.  
  761.     if (!Ifstack->true || !Ifstack->acctrue) {
  762.     pushif(0);
  763.     return;
  764.     }
  765.     programlabel();
  766.     sym = eval(str, 0);
  767.     if (sym->flags) {
  768.     ++Redo;
  769.     Redo_why |= 1 << 11;
  770.     pushif(0);
  771.     Ifstack->acctrue = 0;
  772.     } else {
  773.     pushif(!!sym->value);
  774.     }
  775.     freesymbollist(sym);
  776. }
  777.  
  778. void
  779. v_else(char *str, MNE *dummy)
  780. {
  781.     if (Ifstack->acctrue && !(Ifstack->flags & IFF_BASE)) {
  782.     programlabel();
  783.     Ifstack->true = !Ifstack->true;
  784.     }
  785. }
  786.  
  787. void
  788. v_endif(char *str, MNE *dummy)
  789. {
  790.     IFSTACK *ifs = Ifstack;
  791.  
  792.     if (!(ifs->flags & IFF_BASE)) {
  793.     if (ifs->acctrue)
  794.         programlabel();
  795.     if (ifs->file != Incfile) {
  796.         puts("too many endif's");
  797.     } else {
  798.         Ifstack = ifs->next;
  799.         free(ifs);
  800.     }
  801.     }
  802. }
  803.  
  804. void
  805. v_repeat(char *str, MNE *dummy)
  806. {
  807.     register REPLOOP *rp;
  808.     register SYMBOL *sym;
  809.  
  810.     programlabel();
  811.     sym = eval(str, 0);
  812.     rp = (REPLOOP *)zmalloc(sizeof(REPLOOP));
  813.     rp->next = Reploop;
  814.     rp->file = Incfile;
  815.     rp->seek = ftell(Incfile->fi);
  816.     rp->lineno = Incfile->lineno;
  817.     rp->count = sym->value;
  818.     if ((rp->flags = sym->flags) != 0) {
  819.     ++Redo;
  820.     Redo_why |= 1 << 12;
  821.     }
  822.     Reploop = rp;
  823.     freesymbollist(sym);
  824. }
  825.  
  826. void
  827. v_repend(char *str, MNE *dummy)
  828. {
  829.     if (Reploop) {
  830.     if (Reploop->file == Incfile) {
  831.         if (Reploop->flags == 0 && --Reploop->count) {
  832.         fseek(Incfile->fi,Reploop->seek,0);
  833.         Incfile->lineno = Reploop->lineno;
  834.         } else {
  835.         rmnode((void **)&Reploop, sizeof(REPLOOP));
  836.         programlabel();
  837.         }
  838.         return;
  839.     }
  840.     }
  841.     puts("no repeat");
  842. }
  843.  
  844. static long Seglen;
  845. static long Seekback;
  846.  
  847. void
  848. generate(void)
  849. {
  850.     long seekpos;
  851.     static ulong org;
  852.  
  853.     if (!Redo) {
  854.     if (!(Csegment->flags & SF_BSS)) {
  855.         if (Fisclear) {
  856.         Fisclear = 0;
  857.         if (Csegment->flags & SF_UNKNOWN) {
  858.             ++Redo;
  859.             Redo_why |= 1 << 1;
  860.             return;
  861.         }
  862.         org = Csegment->org;
  863.         if (F_format < 3) {
  864.             putc((org & 0xFF), FI_temp);
  865.             putc(((org >> 8) & 0xFF), FI_temp);
  866.             if (F_format == 2) {
  867.             Seekback = ftell(FI_temp);
  868.             Seglen = 0;
  869.             putc(0, FI_temp);
  870.             putc(0, FI_temp);
  871.             }
  872.         }
  873.         }
  874.         switch(F_format) {
  875.         default:
  876.         case 3:
  877.         case 1:
  878.         if (Csegment->org < org) {
  879.             printf("segment: %s %s  vs current org: %04lx\n",
  880.             Csegment->name, sftos(Csegment->org, Csegment->flags), org);
  881.             asmerr(12, 1);
  882.             exit(1);
  883.         }
  884.         while (Csegment->org != org) {
  885.             putc(OrgFill, FI_temp);
  886.             ++org;
  887.         }
  888.         fwrite(Gen, Glen, 1, FI_temp);
  889.         break;
  890.         case 2:
  891.         if (org != Csegment->org) {
  892.             org = Csegment->org;
  893.             seekpos = ftell(FI_temp);
  894.             fseek(FI_temp, Seekback, 0);
  895.             putc((Seglen & 0xFF), FI_temp);
  896.             putc(((Seglen >> 8) & 0xFF), FI_temp);
  897.             fseek(FI_temp, seekpos, 0);
  898.             putc((org & 0xFF), FI_temp);
  899.             putc(((org >> 8) & 0xFF), FI_temp);
  900.             Seekback = ftell(FI_temp);
  901.             Seglen = 0;
  902.             putc(0, FI_temp);
  903.             putc(0, FI_temp);
  904.         }
  905.         fwrite(Gen, Glen, 1, FI_temp);
  906.         Seglen += Glen;
  907.         }
  908.         org += Glen;
  909.     }
  910.     }
  911.     Csegment->org += Glen;
  912.     if (Csegment->flags & SF_RORG)
  913.     Csegment->rorg += Glen;
  914. }
  915.  
  916. void
  917. closegenerate(void)
  918. {
  919.     if (!Redo) {
  920.     if (F_format == 2) {
  921.         fseek(FI_temp, Seekback, 0);
  922.         putc((Seglen & 0xFF), FI_temp);
  923.         putc(((Seglen >> 8) & 0xFF), FI_temp);
  924.         fseek(FI_temp, 0L, 2);
  925.     }
  926.     }
  927. }
  928.  
  929. void
  930. genfill(int fill, long bytes)
  931. {
  932.     memset(Gen, fill, sizeof(Gen));
  933.     while (bytes > sizeof(Gen)) {
  934.     Glen = sizeof(Gen);
  935.     bytes -= sizeof(Gen);
  936.     generate();
  937.     }
  938.     Glen = bytes;
  939.     generate();
  940. }
  941.  
  942. void
  943. pushif(int bool)
  944. {
  945.     register IFSTACK *ifs = (IFSTACK *)zmalloc(sizeof(IFSTACK));
  946.     ifs->next = Ifstack;
  947.     ifs->file = Incfile;
  948.     ifs->flags = 0;
  949.     ifs->true  = bool;
  950.     ifs->acctrue = Ifstack->acctrue && Ifstack->true;
  951.     Ifstack = ifs;
  952. }
  953.